const cvs = document.querySelector("#waterfall");
const ctx = cvs.getContext("2d");
const cw = (cvs.width = 100),
  ch = (cvs.height = 140);

const GRAVITY = 0.15,
  RATE = 6;

function rand(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

class Particle {
  constructor() {
    // this.ctx = ctx;
    // this.cw = cw;
    // this.ch = ch;
    let newWidth = rand(1, 20);
    let newHeight = rand(1, 45);
    this.x = rand(10 + newWidth / 2, cw - 10 - newWidth / 2);
    this.y = -newHeight;
    this.vx = 0;
    this.vy = 0;
    this.width = newWidth;
    this.height = newHeight;
    this.hue = rand(200, 220);
    this.saturation = rand(30, 60);
    this.lightness = rand(30, 60);
  }

  update() {
    this.vx += this.vx;
    this.vy += GRAVITY;
    this.x += this.vx;
    this.y += this.vy;
  }

  render = function () {
    ctx.strokeStyle =
      "hsla(" +
      this.hue +
      ", " +
      this.saturation +
      "%, " +
      this.lightness +
      "%, .05)";
    ctx.beginPath();
    ctx.moveTo(this.x, this.y);
    ctx.lineTo(this.x, this.y + this.height);
    ctx.lineWidth = this.width / 2;
    ctx.lineCap = "round";
    ctx.stroke();
  };

  renderBubble() {
    ctx.fillStyle = "hsla(" + this.hue + ", 40%, 40%, 1)";
    ctx.fillStyle =
      "hsla(" +
      this.hue +
      ", " +
      this.saturation +
      "%, " +
      this.lightness +
      "%, .3)";
    ctx.beginPath();
    ctx.arc(
      this.x + this.width / 2,
      ch - 20 - rand(0, 10),
      rand(1, 8),
      0,
      Math.PI * 2,
      false
    );
    ctx.fill();
  }
}

class Waterfall {
  // 构造函数，初始化粒子数组
  constructor() {
    this.particles = [];
  }
  // 初始化函数，调用循环函数
  init() {
    this.loop();
  }

  // 重置函数，清空画布和粒子数组
  reset() {
    ctx.clearRect(0, 0, cw, ch);
    this.particles = [];
  }

  // 创建粒子函数，根据RATE创建指定数量的粒子
  create() {
    let i = RATE;
    while (i--) {
      this.particles.push(new Particle());
    }
  }

  // 移除粒子函数，根据粒子位置移除超出画布的粒子
  remove() {
    let i = RATE;
    while (i--) {
      var p = this.particles[i];
      if (p.y > ch - 20 - p.height) {
        p.renderBubble();
        this.particles.splice(i, 1);
      }
    }
  }

  // 更新粒子函数，更新粒子位置
  update() {
    let i = this.particles.length;
    while (i--) {
      const p = this.particles[i];
      p.update(i);
    }
  }

  // 渲染粒子函数，渲染粒子
  render() {
    let i = this.particles.length;
    while (i--) {
      const p = this.particles[i];
      p.render();
    }
  }

  // 清除函数，清除画布上的粒子
  clear() {
    ctx.globalCompositeOperation = "destination-out";
    ctx.fillStyle = "rgba(255,255,255,.06)";
    ctx.fillRect(0, 0, cw, ch);
    ctx.globalCompositeOperation = "lighter";
  }

  // 循环函数，调用创建、更新、渲染、移除粒子函数
  loop() {
    const _this = this;
    let loopit = function () {
      requestAnimationFrame(loopit, cvs);
      _this.clear();
      _this.create();
      _this.update();
      _this.render();
      _this.remove();
    };
    loopit();
  }
}

var waterfall = new Waterfall();
waterfall.reset();
waterfall.init();
